package Filters;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;

import FilesManagers.CantOpenFileException;

/*
Clase encargada de limpiar las stop words.
*****************************************
Por defecto uso stopwords.conf como biblioteca de stop words,
cargo las stop words en memoria cuando se crea el objeto.

Metodos publicos:
*****************
procesarLinea(String linea)
	- recibe una linea de texto y la devuelve sin ninguna stopword



*/
public class StopWordsCleaner extends WordsFilter{

	
	private List<String> pipe;
	private boolean ultimaLinea;
	//private boolean cambieEstadoUltimaLinea;
	private int[] cantidadPorLongitud;
	private ArrayList<List<String>> palabrasDivididas;
	
	public StopWordsCleaner (String bibliotecaStopWords) throws CantOpenFileException{
		 super(bibliotecaStopWords);
		 pipe = new LinkedList<String>();
		 ultimaLinea=false;
		// cambieEstadoUltimaLinea=false;
		 cantidadPorLongitud = new int[5];//Por ahora me manejo con este valor fijo
		 palabrasDivididas = new ArrayList<List<String>>();
		 separarPalabrasSegunLargo();
	}



	public StopWordsCleaner () throws CantOpenFileException{
			this("stopwords.conf");
	}
	
	private int cantidadDePalabras(String linea){
		String[] palabras = linea.split(" ");
		
		return palabras.length;
		
	}
	
	private Iterator<String> getItWordsLength(int longitud){
		Iterator<List<String>> it = this.palabrasDivididas.iterator();
		while(it.hasNext()){
			List<String> l =it.next();
			if(!l.isEmpty() && (cantidadDePalabras(l.get(0)))==longitud)
				return l.iterator();
		}
		return null;
		
	}
	private void separarPalabrasSegunLargo(){
		
		ArrayList<String> a = new ArrayList<String>();
		Iterator<String> it=this.getListaPalabras().iterator();
		String palabra="";
		int cantPalabras=0;
		while(it.hasNext()){
			String palabraTemp=it.next();
			//if(cantidadDePalabras(palabraTemp)==5)System.out.println("EHHHHHHHHH MIRAME "+palabraTemp+" cantPalabras"+cantPalabras);
			if(cantidadDePalabras(palabraTemp)<=cantPalabras){
				//palabra=palabraTemp;
				//cantPalabras =cantidadDePalabras(palabraTemp);
				a.add(palabraTemp);
			}else{
				Collections.sort(a);
				this.palabrasDivididas.add(a);
				a = new ArrayList<String>();
				a.add(palabraTemp);
				
			}
			palabra=palabraTemp;
			cantPalabras =cantidadDePalabras(palabra);
			
		}
		Collections.sort(a);
		this.palabrasDivididas.add(a);
	}

	protected String filterWords(String lineaOrigen){
		
		lineaOrigen=lineaOrigen.trim();
		boolean borreStopWord=false;
		//if(!ultimaLinea){
			String []aux = lineaOrigen.split(" ");
			if(aux.length==0){ // Aparentemente este if esta de mas ---
				
				aux = new String[1];
				aux[1]=lineaOrigen;
			}
			for(int i=0; i<cantidadDePalabras(lineaOrigen)/*aux.length*/;i++){
				if(!aux[i].equals(""))this.pipe.add(aux[i]);
			}
		//}
		
		StringBuffer resultado= new StringBuffer("");
		int largoPalabra=5;
		//boolean flag=false;
		
		/*Si es la ultima linea tengo que procesar todo lo que tengo en el pipe*/
		if((ultimaLinea)/*&&(!flag)*/) {
			//flag=true;/*ultimaLinea=false;*/
			largoPalabra = this.pipe.size();
							
		}
		
		/*Si al menos tengo 5 palabras o es la ultima linea*/
		while(((this.pipe.size() >=5)||(ultimaLinea))){
			
					
			while((largoPalabra>0)||(ultimaLinea)){
				//if((ultimaLinea))ultimaLinea=false;
				StringBuffer palabraBuffer= new StringBuffer();
				Iterator<String> itPipe = this.pipe.iterator();
				for(int j=0; j<largoPalabra;j++){
					if(itPipe.hasNext())palabraBuffer.append(" ").append(/*this.pipe.get(j)*/itPipe.next());
					
				}
				
				/*Para eliminar el primer espacio blanco*/
				String palabra = palabraBuffer.toString().trim();
				//System.out.println("la palara quedo  "+ palabra);
				//System.out.println("La palabra es: "+palabra);
				if(!palabra.trim().equals("")){
					/*Iterador de StopWords*/
					//Iterator<String> stopIt = getListaPalabras().iterator();
					Iterator<String> stopIt = this.getItWordsLength(largoPalabra);
					/*Recorro cada una de las stopWords*/
					while(stopIt!=null && stopIt.hasNext()){		
						String stopWord = stopIt.next();
						//System.out.println("La stopwords es "+ stopWord);
						/*Si era una stopWord la elimino y debo correr el pipe*/
						
						//System.out.println("Palabra "+palabra+" y stopword "+stopWord);
							
						if (Pattern.compile("^"+stopWord+"$").matcher(palabra).find()){
						/*if(stopWord.indexOf("+")==-1 && stopWord.indexOf("|")==-1){
							if(palabra.length()==stopWord.length())palabra=palabra.replace(stopWord,"");
						}else{
							palabra=palabra.replaceAll("^"+stopWord+"$", "");
						}
						
						if(palabra.equals("")){ */
						//if(palabra.equals(stopWord)){
							palabra="";
						//if(Pattern.matches(palabra,stopWord)){
							//System.out.println("Era una StopW: "+palabra);
							borreStopWord=true;
							/*Aca corro el pipe*/
							for(int k=0;k<largoPalabra;k++){
								this.pipe.remove(0);//siempre borro el 0, porq el indice se corre
							}
							break;//Si borre la StopWord, no sigo iterando las stopwords.
						}else{
							//Como mantengo las stopWords ordenadas, si me pase (orden alfabetico) entonces corto
							// No comparo la palabra completa por como esta implementado el stopwords.conf(con ExpReg)
							if(palabra.substring(0,1).compareTo(stopWord.substring(0,1))<0){
								//System.out.println("Comparo "+palabra.substring(0,1)+" y "+stopWord.substring(0,1)+" y me da "+palabra.substring(0,1).compareTo(stopWord.substring(0,1)));
								break;
							}
						}
					}
					//if((this.pipe.size()==0))break;
					/*Debo decrementar la cantidad de palabras a comparar en el pipe en la proxima vuelta*/
				//}
			
				if(borreStopWord){
					borreStopWord=false;
					if(this.pipe.size()>=5){
						largoPalabra = 5;
					}else{
						if(ultimaLinea)largoPalabra = this.pipe.size();
					}
				}else{
					if(largoPalabra>0){
						largoPalabra--;
						if(largoPalabra==0)break;
					}else{
						
						if(ultimaLinea && this.pipe.size()==0){break;/*ultimaLinea=false;*/}
						
						
					}
				}
				}else{
				      if(ultimaLinea) break;
				}
				
				//System.out.println("Largo de palabra es: "+largoPalabra);
			}
			
			
			/*Si probe con 5,4,..1 y no encontre stopWord entonces devuelvo la primera palabra del pipe y la elimino*/
			if(largoPalabra==0 && !borreStopWord){
				//System.out.println("Largo palabra 0 y no borre stopWord");
				if(this.pipe.size()>0){
					//System.out.println("Todo bien, la saco del pipe: "+this.pipe.get(0));
				    resultado.append(" ").append(this.pipe.get(0));
				    //System.out.println("El largo palabra antes de sacar del pipe es ----- : "+this.pipe.size());
				    /*for (int i=0; i<this.pipe.size();i++){
				    	System.out.println("y el pipe tiene "+this.pipe.get(i));
				    	
				    }*/
				    
					this.pipe.remove(0);
					if(this.pipe.size()>=5){
						largoPalabra = 5;
					}else{
						largoPalabra = this.pipe.size();
						//System.out.println("El largo palabra despues de sacar del pipe es ----- : "+largoPalabra);
					}
					//System.out.println("El largo palabra despues de sacar del pipe es : "+largoPalabra);
				}
				if(ultimaLinea && this.pipe.size()==0 && largoPalabra==0 )break;
			}
			if(ultimaLinea && this.pipe.size()==0 && largoPalabra==0 )break;
		}
		
		//if(!resultado.trim().equals("")) System.out.println("Devuelvo "+resultado);
		return resultado.toString().trim();
		

	}
	
	public String procesarLinea(String linea, boolean ultimaLinea){
		this.ultimaLinea=ultimaLinea;
		linea=filterWords(linea);
		return linea;


	}
	public void setUltimaLinea(boolean b) {
		this.ultimaLinea=b;
		//cambieEstadoUltimaLinea=false;
		
	}



	@Override
	protected void ordenarPalabras() {
		// TODO Apéndice de método generado automáticamente
		Collections.sort(listaPalabras,  new StopWordsComparator());
		
	}

}